#include "KeyboardElement.h"

namespace OpenNano
{
    REGISTER_OBJECT_FACTORY( KeyboardElement, KEYBOARD_TAG );

    KeyboardElement::KeyboardElement(TiXmlElement *element):
                    ConfigElement(element), logger(log4cplus::Logger::getInstance( KEYBOARD_TAG )),
                    _interpreter(), _keymaps(), _everything_is_good_so_far(true)
            {
            }

    KeyboardElement::~KeyboardElement()
    {
        _keymaps.clear();
    }

    void KeyboardElement::init()
    {
        LOG4CPLUS_INFO(logger, "Keyboard element: initialized");
    }

    const std::string& KeyboardElement::getInterpreter() const
    {
        return _interpreter;
    }

    const KeyMaps& KeyboardElement::getKeyMaps() const
    {
        return _keymaps;
    }

    bool KeyboardElement::getKeyMap(const std::string& name, std::string &value)
    {
        bool keymap_found = false;
        KeyMaps::iterator it = _keymaps.find (name);
        if (it != _keymaps.end() )
        {
            value= it->second;
            keymap_found=true;
        }
        else
        {
            LOG4CPLUS_WARN(logger, "Keymap not found:");
            LOG4CPLUS_WARN(logger, name);
        }
        return keymap_found;
    }

   void KeyboardElement::attributeFound(TiXmlAttribute * attribute)
    {
        if ( attribute->NameTStr().compare(KEYBOARD_INTERPRETER_ATTRIBUTE) == 0 )
        {
            _interpreter=attribute->ValueStr();
        }
        else
        {
            //attribute not recognized
            LOG4CPLUS_WARN(logger, "Attribute not recognized:");
            LOG4CPLUS_WARN(logger, attribute->NameTStr());

            unknownAttributeFound(attribute);
            _everything_is_good_so_far=false;
        }
    }

    void KeyboardElement::childElementFound(TiXmlElement * childElement)
    {
        if ( childElement->ValueStr().compare(KEYMAP_TAG) == 0 )
        {
            TiXmlAttribute * param = childElement->FirstAttribute();
            if ( param && param->NameTStr().compare(KEYMAP_KEY_ATTRIBUTE) == 0 &&
                        param->Next() && param->Next()->NameTStr().compare(KEYMAP_ACTION_ATTRIBUTE) == 0 )
            {
                //NOTE_TO_SELF:
                //if there are two parameter element with the same name
                //in the map there will be only one entry, with the value defined
                //in the last parsed element.
                _keymaps[ param->ValueStr() ] = param->Next()->ValueStr();
            }
            else
            {
                LOG4CPLUS_WARN(logger, "Name attribute of the keymap element not found/invalid");
                //parameter attribute not found/recognized
                _everything_is_good_so_far=false;
            }
        }
        else
        {
            //Element not recognized
            LOG4CPLUS_WARN(logger, "Child element not recognized:");
            LOG4CPLUS_WARN(logger, childElement->ValueStr());

            unknownElementFound(childElement);
            _everything_is_good_so_far=false;
        }
    }

    void KeyboardElement::textFound(const char* text)
    {
        LOG4CPLUS_WARN(logger, "Text not recognized:");
        LOG4CPLUS_WARN(logger, text);

        unknownTextFound(text);
    }

    bool KeyboardElement::postConfiguration()
    {
        return (!_interpreter.empty()) && _everything_is_good_so_far;
    }



}
